﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Wizard.Statements;

namespace Wizard.Source
{
    public class StatementInfo
    {
        internal string mStatementName;
        internal Type mStatementType;
        internal ConstructorInfo mConstructorInfo;
        internal IDictionary<String, StatementFieldInfo> mStatementFields;
        internal IDictionary<String, LocalVariableFieldInfo> mLocalVariablesFields;
        internal IDictionary<String, BlockFieldInfo> mInnerBlocks;

        public StatementInfo(Type statementType)
        {
            mStatementType = statementType;
            mStatementName = statementType.Name;
            mStatementFields = new Dictionary<String, StatementFieldInfo>(StringComparer.OrdinalIgnoreCase);
            mLocalVariablesFields = new Dictionary<String, LocalVariableFieldInfo>(StringComparer.OrdinalIgnoreCase);
            mInnerBlocks = new Dictionary<String, BlockFieldInfo>(StringComparer.OrdinalIgnoreCase);

            foreach (var fi in mStatementType.GetFields(
                BindingFlags.Instance
                | BindingFlags.NonPublic
                | BindingFlags.Public))
            {
                var pa = fi.GetCustomAttributes(typeof(FieldAttribute), true);
                if (pa != null && pa.Length > 0)
                {
                    mStatementFields[fi.Name] = new StatementFieldInfo(fi, pa);
                    continue;
                }
                pa = fi.GetCustomAttributes(typeof(BlockAttribute), true);
                if (pa != null && pa.Length > 0)
                {
                    mInnerBlocks[fi.Name] = new BlockFieldInfo(fi, pa);
                    continue;
                }
                pa = fi.GetCustomAttributes(typeof(VariableAttribute), true);
                if (pa != null && pa.Length > 0)
                {
                 //   mLocalVariablesFields[fi.Name] = new LocalVariableFieldInfo(fi, pa);
                    continue;
                }
                throw new Exception(
                    string.Format(
                        "Field {0} in Statement {1} must have an attribute set (Field, Block or Variable).\n", 
                        fi.Name,
                        mStatementName));
            }
            mConstructorInfo = statementType.GetConstructor(new Type[] {});
        }
    }
}